import { createBrowserHistory } from "history";
import React, {
  createContext,
  useContext,
  useLayoutEffect,
  useMemo,
  useRef,
  useState,
} from "react";

// 把 <Route /> 的嵌套，转成一棵树。
const createRoutesFormChildren = (children) => {
  const routes = [];
  React.Children.forEach(children, (node) => {
    let route = {
      path: node.props.path,
      element: node.props.element,
    };
    if (node.props.children) {
      route.children = createRoutesFormChildren(node.props.children);
    }
    routes.push(route);
  });
  console.log("routes", routes);
  return routes;
};

// const Routing = () => useRoutes(routes)
// Routing 就是 我根据 routes 参数的内容，
// 结合当前浏览器上的 url， 返回具体是哪个 element
const useRoutes = (routes) => {
  const location = useLocation(); // 当前路径
  const currentPath = location.pathname || "/";
  console.log("currentPath", currentPath);
  for (let i = 0; i < routes.length; i++) {
    let { path, element } = routes[i];
    let match = currentPath.match(new RegExp(`^${path}`));
    if (match) {
      console.log("element", element);
      return element;
    }
  }
  return null;
};

// 创建上下文
const NavigationContext = createContext({});
const LocationContext = createContext({});

const useLocation = () => useContext(LocationContext).location;
// const useNavigate = () => useContext(NavigationContext).navigator;

export const BrowserRouter = ({ children }) => {
  let historyRef = useRef(null);
  if (historyRef.current === null) {
    historyRef.current = createBrowserHistory();
  }
  let history = historyRef.current;
  console.log("history", history);
  const [state, setState] = useState({
    action: history.action,
    location: history.location,
  });
  useLayoutEffect(() => history.listen(setState), [history]);

  return (
    <Router
      children={children}
      location={state.location}
      navigator={history}
      navigationType={state.action}
    />
  );
};

const Router = ({ children, location: locationPorp, navigator }) => {
  const navigationContext = useMemo(() => ({ navigator }), [navigator]);
  const locationContext = useMemo(
    () => ({ location: locationPorp }),
    [locationPorp]
  );

  return (
    <NavigationContext.Provider value={navigationContext}>
      <LocationContext.Provider value={locationContext}>
        {children}
      </LocationContext.Provider>
    </NavigationContext.Provider>
  );
};

export const Route = () => {};

// Routes 这个东西，
// 我就是要把所有的 Route 组件，创建成一棵树
export const Routes = ({ children }) =>
  useRoutes(createRoutesFormChildren(children));
